import { Color, Material, Mesh, MeshBasicMaterial, MeshLambertMaterial, MeshPhongMaterial, MeshStandardMaterial, Object3D } from 'three';
import { Command } from '../command.js';
import { Editor } from '../editor.js';

/**
 * @param editor Editor
 * @param object THREE.Object3D
 * @param attributeName string
 * @param newValue integer representing a hex color value
 * @constructor
 */
class SetMaterialColorCommand<M extends Material|MeshBasicMaterial|MeshStandardMaterial|MeshPhongMaterial|MeshLambertMaterial|MeshLambertMaterial,K extends keyof M> extends Command {
	private object:Mesh;
	private material?:M;
	private oldValue:number;
	private newValue:number;
	attributeName:K;
	constructor( editor:Editor, object:Object3D,material:M, attributeName:K, newValue:number, materialSlot:number ) {

		super( editor );

		this.type = 'SetMaterialColorCommand';
		this.name = `Set Material.${attributeName.toString()}`;
		this.updatable = true;

		this.object = object as Mesh;
		this.material = ( this.object !== undefined ) ? this.editor.getObjectMaterial( this.object, materialSlot ) as M : undefined;

		this.oldValue = ( this.material !== undefined ) ? (this.material[ attributeName ] as Color).getHex() : undefined;
		this.newValue = newValue;

		this.attributeName = attributeName;

	}

	execute() {
		if(this.material)
		(this.material[ this.attributeName ] as Color).setHex( this.newValue );

		this.editor.signals.materialChanged.dispatch( this.material );

	}

	undo() {
		if(this.material)
		(this.material[ this.attributeName ] as Color).setHex( this.oldValue );

		this.editor.signals.materialChanged.dispatch( this.material );

	}

	update( cmd:SetMaterialColorCommand<M,K> ) {

		this.newValue = cmd.newValue;

	}


}

export { SetMaterialColorCommand };
